package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.commons.ex.ServiceException;
import cn.tedu.csmall.commons.web.ServiceCode;
import cn.tedu.csmall.product.mapper.BrandCategoryMapper;
import cn.tedu.csmall.product.mapper.CategoryAttributeTemplateMapper;
import cn.tedu.csmall.product.mapper.CategoryMapper;

import cn.tedu.csmall.product.mapper.SPUMapper;
import cn.tedu.csmall.product.pojo.entity.BrandCategory;
import cn.tedu.csmall.product.pojo.entity.Category;
import cn.tedu.csmall.product.pojo.entity.CategoryAttributeTemplate;
import cn.tedu.csmall.product.pojo.entity.SPU;
import cn.tedu.csmall.product.pojo.param.CategoryAddNewParam;
import cn.tedu.csmall.product.pojo.param.CategoryUpdateInfoParam;
import cn.tedu.csmall.product.pojo.vo.CategoryListItemVO;
import cn.tedu.csmall.product.pojo.vo.CategoryStandardVO;
import cn.tedu.csmall.product.pojo.vo.CategoryTreeItemVO;
import cn.tedu.csmall.product.service.ICategoryService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class CategoryServiceImpl implements ICategoryService {
    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BrandCategoryMapper brandCategoryMapper;

    @Autowired
    private CategoryAttributeTemplateMapper categoryAttributeTemplateMapper;

    @Autowired
    private SPUMapper spuMapper;

    @Override
    public void addNew(CategoryAddNewParam categoryAddNewParam) {
        log.debug("开始处理【添加分类】的业务，参数：{}" ,categoryAddNewParam);
        //判断分类名称是否被占用
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", categoryAddNewParam.getName())
                .eq("parent_id", categoryAddNewParam.getParentId());
        int countByName = categoryMapper.selectCount(queryWrapper);
        log.debug("根据分类名称统计匹配的分类，结果：{}" , countByName);
        if (countByName>0){
            String message = "添加分类失败,分类名称已被占用";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //检查parent_id是否存在
        if (categoryAddNewParam.getParentId() != 0) {
            QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
            categoryQueryWrapper.eq("id", categoryAddNewParam.getParentId());
            Integer integer = categoryMapper.selectCount(categoryQueryWrapper);
            log.debug("根据分类父级id统计匹配的id，结果：{}", integer);
            if (integer == 0) {
                String message = "添加分类失败,父级id不存在！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
            }

            //层级是否合法
            CategoryStandardVO categoryStandardVO = categoryMapper.getStandard(categoryAddNewParam.getParentId());
            if (categoryStandardVO.getDepth() + 1 != categoryAddNewParam.getDepth()) {
                String message = "添加分类失败,层级depth不合法！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
            }
            if (categoryStandardVO.getIsParent() == 0) {
                categoryStandardVO.setIsParent(1);
                Category category = new Category();
                BeanUtils.copyProperties(categoryStandardVO, category);
                category.setGmtModified(LocalDateTime.now());
                int i = categoryMapper.updateById(category);
                if (i != 1) {
                    String message = "修改失败，服务器忙，请稍后再试！";
                    log.warn(message);
                    throw new ServiceException(ServiceCode.ERR_UPDATE,message);
                }
            }
        } else {
            if (categoryAddNewParam.getDepth() != 1) {
                String message = "添加分类失败,层级depth不合法！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
            }
        }

        //将是否为父类  变为0
        if (categoryAddNewParam.getIsParent() != 0) {
            categoryAddNewParam.setIsParent(1);
        }

        //将分类加入到数据库中
        Category category = new Category();
        BeanUtils.copyProperties(categoryAddNewParam,category);
        category.setGmtCreate(LocalDateTime.now());
        category.setGmtModified(LocalDateTime.now());
        log.debug("准备将新的分类数据写入到数据库，数据：{}" , category);
        int insert = categoryMapper.insert(category);

        if (insert != 1) {
            String message = "添加失败，服务器忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }

        log.debug("将新的分类数据写入到数据库，完成！");
    }

    @Override
    public void delete(Long id) {

        log.debug("开始处理【通过id删除分类】的业务，参数：{}" ,id);
        //判断id是否存在
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
        int countByName = categoryMapper.selectCount(queryWrapper);
        log.debug("根据分类id统计匹配的分类数量，结果：{}" , countByName);
        if (countByName==0){
            String message = "没有此id";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        //检查brand_category中有无数据和分类有关联
        log.debug("检查brand_category中有无数据和分类有关联!");
        QueryWrapper<BrandCategory> queryWrapperBC = new QueryWrapper<>();
        queryWrapperBC.eq("category_id",id);
        int countInBrandCategory = brandCategoryMapper.selectCount(queryWrapperBC);
        log.debug("根据分类id统计匹配的品牌分类数量，结果：{}" , countInBrandCategory);
        if (countInBrandCategory != 0){
            String message = "存在品牌分类和分类关联！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //检查category_attribute_template中有无数据和category有关联
        log.debug("检查category_attribute_template中有无数据和分类有关联!");
        QueryWrapper<CategoryAttributeTemplate> queryWrapperCAT = new QueryWrapper<>();
        queryWrapperCAT.eq("category_id",id);
        int countInCAT = categoryAttributeTemplateMapper.selectCount(queryWrapperCAT);
        log.debug("根据分类id统计匹配的品牌属性模板数量，结果：{}" , countInCAT);
        if (countInCAT != 0){
            String message = "存在分类属性模板和分类关联！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //检查spu中有无数据和category有关联
        log.debug("检查spu中有无数据和分类有关联!");
        QueryWrapper<SPU> queryWrapperSPU = new QueryWrapper<>();
        queryWrapperSPU.eq("category_id",id);
        int countInSPU = spuMapper.selectCount(queryWrapperSPU);
        log.debug("根据分类id统计匹配的SPU数量，结果：{}" , countInSPU);
        if (countInSPU != 0){
            String message = "存在SPU和分类关联！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //检查是否有下级元素
        log.debug("检查是否有下级元素");
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.eq("parent_id", id);
        Integer integer = categoryMapper.selectCount(categoryQueryWrapper);
        if (integer != 0){
            String message = "存在下级元素，不能删除！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //如果是上级元素的最后一个。则将上级元素的is_parent改为0
        log.debug("如果是上级元素的最后一个.则将上级元素的is_parent改为0");
        CategoryStandardVO categoryStandardVO = categoryMapper.getStandard(id);
        QueryWrapper<Category> categoryQueryWrapper1 = new QueryWrapper<>();
        categoryQueryWrapper1.eq("parent_id", categoryStandardVO.getParentId());
        Integer integer1 = categoryMapper.selectCount(categoryQueryWrapper1);
        log.debug("上级元素的子元素个数为：{}", integer1);
        if (integer1 == 1){
            CategoryStandardVO categoryStandardVO1 = categoryMapper.getStandard(categoryStandardVO.getParentId());
            categoryStandardVO1.setIsParent(0);
            Category category = new Category();
            BeanUtils.copyProperties(categoryStandardVO1, category);
            category.setGmtModified(LocalDateTime.now());
            categoryMapper.updateById(category);
        }

        //开始删除
        int i = categoryMapper.deleteById(id);
        if (i != 1) {
            String message = "删除失败，服务器忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_DELETE,message);
        }
        log.debug("通过id删除分类数据，完成！");
    }


    @Override
    public void updateById(Long categoryId, CategoryUpdateInfoParam categoryUpdateInfoParam) {
        log.debug("开始处理【通过id修改分类】的业务，参数：{}" ,categoryId);
        //if (id<=0)在参数中配置此情况
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",categoryId);
        int countByName = categoryMapper.selectCount(queryWrapper);
        log.debug("根据相册id统计匹配的相册数量，结果：{}" , countByName);
        if (countByName==0){
            String message = "没有此id号呀";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        Category category = categoryMapper.selectById(categoryId);
        category.setName(categoryUpdateInfoParam.getName());
        category.setKeywords(categoryUpdateInfoParam.getKeywords());
        category.setSort(categoryUpdateInfoParam.getSort());
        category.setIcon(categoryUpdateInfoParam.getIcon());

        int i = categoryMapper.updateById(category);

        if (i != 1) {
            String message = "修改失败，服务器忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }

        log.debug("通过id修改分类数据，完成！");
    }

    @Override
    public void Enable(Long id) {
        log.debug("开始处理【启用】业务！参数：{}", id);
        updateEnableById(id, 1);
    }

    @Override
    public void Disable(Long id) {
        log.debug("开始处理【禁用】业务！参数：{}", id);
        updateEnableById(id, 0);
    }

    @Override
    public void updateEnableById(Long id, Integer value) {
        //判断此id是否存在
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.eq("id", id);
        Integer integer = categoryMapper.selectCount(categoryQueryWrapper);
        if (integer == 0) {
            String message = "修改失败，此id不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        //开始修改
        Category category = new Category();
        category.setId(id)
                .setEnable(value);
        int i = categoryMapper.updateById(category);
        if (i == 0) {
            String message = "修改失败，服务器忙，请稍后再试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
    }

    @Override
    public List<CategoryListItemVO> listCategory(Long id) {
        log.debug("开始处理【根据父级id查询列表】的业务，参数：{}", id);
        //判断此id是否存在
        if (id != 0) {
            QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
            categoryQueryWrapper.eq("id", id);
            Integer integer = categoryMapper.selectCount(categoryQueryWrapper);
            if (integer == 0) {
                String message = "查询失败，此id不存在！";
                log.warn(message);
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
            }
        }

        //判断此id有没有子类
//        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
//        categoryQueryWrapper.eq("parent_id", id);
//        Integer integer = categoryMapper.selectCount(categoryQueryWrapper);
//        if (integer == 0) {
//            return null;
//        }

        List<CategoryListItemVO> listByParentId = categoryMapper.getListByParentId(id);
        log.debug("处理【根据父级id查询列表】业务完毕！");
        return listByParentId;
    }

    @Override
    public CategoryStandardVO getStandard(Long id) {
        //判断id是否存在
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.eq("id", id);
        Integer integer = categoryMapper.selectCount(categoryQueryWrapper);
        if (integer == 0) {
            String message = "查询失败，此id不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        //开始查询
        CategoryStandardVO categoryStandardVO = categoryMapper.getStandard(id);
        return categoryStandardVO;
    }

    @Override
    public List<CategoryTreeItemVO> listTree() {
        log.debug("开始处理【查询分类树状列表】的业务！");
        List<CategoryTreeItemVO> categoryTreeItemVOList = new ArrayList<>();

        List<CategoryListItemVO> categoryListItemVOList = categoryMapper.list();
        for (CategoryListItemVO categoryListItemVO : categoryListItemVOList) {
            if (categoryListItemVO.getParentId() == 0) {
                CategoryTreeItemVO categoryTreeItemVO = convertListItemToTreeItem(categoryListItemVO);
                categoryTreeItemVOList.add(categoryTreeItemVO);

                fillChildren(categoryTreeItemVO, categoryListItemVO, categoryListItemVOList);
            }
        }
        log.debug("处理【查询分类树状列表】业务完毕！");
        return categoryTreeItemVOList;
    }

    private void fillChildren(CategoryTreeItemVO categoryTreeItemVO, CategoryListItemVO categoryListItemVO, List<CategoryListItemVO> categoryListItemVOList) {
        if (categoryListItemVO.getIsParent() == 1) {
            categoryTreeItemVO.setChildren(new ArrayList<>());
            for (CategoryListItemVO categoryListItemVO1 : categoryListItemVOList) {
                if (categoryListItemVO1.getParentId() == categoryListItemVO.getId()) {
                    CategoryTreeItemVO categoryTreeItemVO1 = convertListItemToTreeItem(categoryListItemVO1);
                    categoryTreeItemVO.getChildren().add(categoryTreeItemVO1);

                    fillChildren(categoryTreeItemVO1,categoryListItemVO1,categoryListItemVOList);
                }
            }
        }
    }

    public CategoryTreeItemVO convertListItemToTreeItem(CategoryListItemVO categoryListItemVO) {
        return new CategoryTreeItemVO().setValue(categoryListItemVO.getId())
                .setLabel(categoryListItemVO.getName());
    }
}
